package com.healthcarex.hip.saas.message.adapter.sdk;


import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.healthcarex.hip.saas.common.util.xml.JaxbUtils;
import com.healthcarex.hip.saas.message.core.AbstractMessage;
import com.healthcarex.hip.saas.message.core.MessageConstant;
import com.healthcarex.hip.saas.message.core.MessageModel;
import com.healthcarex.hip.saas.message.factory.MessageFactory;
import com.healthcarex.hip.saas.message.hl7.v3.model.PatientRegistryAddRequest;
import com.healthcarex.hip.saas.message.model.HIPMSG;
import com.healthcarex.hip.saas.message.model.Message;
import com.healthcarex.hip.saas.message.schema.MessageSchemaDefinition;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author ChenPan
 * @date 2018/7/24 14:14
 * description: 消息转换器
 */
public class MessageConverter {


    /**
     * 字符串消息转换为消息实体
     *
     * @param schemaContent 消息结构定义json
     * @param message       字符串消息
     * @param msgType       消息类型 V2/V3
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     * @throws Exception
     */
    public static MessageModel msg2Model(String schemaContent, String message, String msgType)
            throws JsonParseException, JsonMappingException, IOException, Exception {
        if ((MessageConstant.MESSAGE_TYPE_V2.equals(msgType)) && (message.indexOf("\r") == -1)) {
            message = message.replaceAll("\n", "\r");
        }
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> schema = (Map) mapper.readValue(schemaContent, HashMap.class);
        MessageSchemaDefinition msd = new MessageSchemaDefinition();
        msd.setSchema(schema);
        MessageModel model = MessageFactory.parseMessage(msgType, message, msd);
        return model;
    }

    /**
     * 消息实体转换为字符串
     *
     * @param schemaContent   消息结构定义json
     * @param templateContent 消息模板
     * @param msgType         消息类型 V2/V3
     * @param model           消息模型
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     * @throws Exception
     */
    public static String model2Msg(String schemaContent, String templateContent, String msgType, MessageModel model)
            throws JsonParseException, JsonMappingException, IOException, Exception {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> schema = (Map) mapper.readValue(schemaContent, HashMap.class);
        MessageSchemaDefinition msd = new MessageSchemaDefinition();
        msd.setSchema(schema);
        msd.setTemplate(templateContent);
        AbstractMessage ret = MessageFactory.generateMessage(msgType, model, msd);
        return ret.getMessage().toString();
    }

    /**
     * v3 xml消息转V3消息实体
     *
     * @param schemaName 结构定义文件名称
     * @param message    消息内容
     * @param v3Model    V3实体bean
     * @return
     * @throws IOException
     */
    public static Message v3xml2Model(String schemaName, String message, Message v3Model) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> schema = (Map) mapper.readValue(
                new ClassPathResource("schemas/" + schemaName + ".json").getInputStream(), HashMap.class);
        MessageSchemaDefinition msd = new MessageSchemaDefinition();
        msd.setSchema(schema);
        MessageModel model = MessageFactory.parseMessage(MessageConstant.MESSAGE_TYPE_V3, message, msd);
        v3Model = JSON.parseObject(JSON.toJSONString(model.getContent()), v3Model.getClass());
        return v3Model;
    }

    /**
     * V3消息实体转v3 xml字符串
     *
     * @param schemaName   结构定义文件名称
     * @param templateName xml模板文件名称
     * @param v3Model      V3实体bean
     * @return
     * @throws IOException
     */
    public static String model2xml(String schemaName, String templateName, Message v3Model) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> schema = (Map) mapper.readValue(
                new ClassPathResource("schemas/" + schemaName + ".json").getInputStream(), HashMap.class);
        String xml = FileUtils.readFileToString(new File(
                        MessageConverter.class.getClassLoader()
                                .getResource("templates/" + templateName + ".xml")
                                .getFile()
                ),
                "UTF-8");
        MessageSchemaDefinition msd = new MessageSchemaDefinition();
        msd.setSchema(schema);
        msd.setTemplate(xml);

        MessageModel model = new MessageModel();
        model.setContent((Map<String, Object>) JSON.toJSON(v3Model));

        AbstractMessage ret = MessageFactory.generateMessage(MessageConstant.MESSAGE_TYPE_V3, model, msd);
        return ret.getMessage().toString();
    }

    /**
     * 包装HIP平台格式报文
     *
     * @param serviceId
     * @param msgBody
     * @return
     */
    public static String warpHipV3Msg(String serviceId, String msgBody) {

        HIPMSG msg = new HIPMSG();
        HIPMSG.Head head = msg.createHead();
        head.setCreateTime(System.currentTimeMillis() / 1000);
        head.setReqId(UUID.randomUUID().toString());
        head.setFormat(HIPMSG.FormatType.xml.name());
        head.setMsgType(HIPMSG.MsgType.V3.name());
        head.setService(serviceId);

        msg.createBody(msgBody);

        return JaxbUtils.convertToXml(msg);
    }

    /**
     * 抽取HIP平台格式报文头
     *
     * @param hipMsg
     * @return
     */
    public static Map<String, Object> extractHipMsgHead(String hipMsg) {
        HIPMSG msg = JaxbUtils.convertToBean(hipMsg, HIPMSG.class);
        return (Map<String, Object>) JSON.toJSON(msg.getHead());
    }

    /**
     * 抽取HIP平台格式报文体内容
     *
     * @param hipMsg
     * @return
     */
    public static String extractHipMsgBody(String hipMsg) {
        HIPMSG msg = JaxbUtils.convertToBean(hipMsg, HIPMSG.class);

        return msg.getBody().getContent();
    }
}
